home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
utility
/
freedos.zip
/
COM050.ZIP
/
COMMAND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-17
|
14KB
|
665 lines
/*
* COMMAND.C - command-line interface.
*
* Version: 0.50
*
* Comments:
*
* 06/17/94 (Tim Norman) ---------------------------------------------------
* started.
*
* 08/08/95 (Matt Rains) ---------------------------------------------------
* i have cleaned up the source code. changes now bring this source into
* guidelines for recommended programming practice.
*
* i have added the the standard FreeDOS GNU licence test to the
* initialize() function.
*
* i have started to replease puts() with printf(). this will help
* standardize output. please follow my lead.
*
* i have added some constants to help making changes easier.
*
* 12/15/95 (Tim Norman) ---------------------------------------------------
* major rewrite of the code to make it more efficient and add
* redirection support (finally!)
*
* 1/6/96 (Tim Norman) -----------------------------------------------------
* finished adding redirection support!!! Changed to use our own exec
* code (MUCH thanks to Svante Frey!!
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include <process.h>
#include <time.h>
#include <errno.h>
#include <dir.h>
#include <fcntl.h>
#include <io.h>
#include <sys\stat.h>
#include "command.h"
#define DEBUG
#define SYNTAXERR "ERROR: syntax error"
#define NOENVERR "ERROR: no environment"
#define INVALIDDRIVE "ERROR: invalid drive"
#define INVALIDFUNCTION "ERROR: invalid function"
#define FILENOTFOUND "ERROR: file not found"
#define ACCESSDENIED "ERROR: access denied"
#define NOTENOUGHMEMORY "ERROR: not enough memory"
#define BADENVIROMENT "ERROR: bad enviroment"
#define BADFORMAT "ERROR: bad format"
#define ERROR_E2BIG "ERROR: Argument list too long"
#define ERROR_EINVAL "ERROR: Invalid argument"
#define PROMPT "prompt"
#define EXIT "exit"
#define CD "cd"
#define DOSKEY "doskey"
#define DIR "dir"
#define REM "rem"
#define SET "set"
#define VER "ver"
#define MD "md"
#define RD "rd"
#define DEL "del"
#define REN "ren"
char exitflag = 0; /* indicates EXIT was typed */
char canexit = 1; /* indicates if this shell is exitable */
/*
* fatal error handler.
*
*
*/
void fatal_error(char *s)
{
printf("fatal_error() : %s\n", s);
exit(100);
}
/*
* is character a delimeter when used on first word?
*
*
*/
char is_delim(char c)
{
return(c == '/' || c == '=' || c == 0 || isspace (c));
}
/*
* strip the extra spaces between parameters on command-line. quotation
* mark aware.
*
*/
int strip(char *command)
{
unsigned char place = 0;
unsigned char tempplace = 0;
unsigned char firstword = 1;
unsigned char inquote = 0;
char temp[128] = "";
char foundspace = 0;
while(isspace(command[place]))
{
place++;
}
while(command[place])
{
if(foundspace && !isspace(command[place]))
{
temp[tempplace++] = ' ';
foundspace = 0;
}
if (isspace (command[place]) && !inquote)
{
foundspace = 1;
firstword = 0;
}
else if(is_delim(command[place]) && firstword)
{
temp[tempplace++] = ' ';
temp[tempplace++] = command[place];
}
else if (command[place] == '"')
{
if(!inquote && place > 0 && !isspace(command[place - 1]))
{
temp[tempplace++] = ' ';
}
temp[tempplace++] = '"';
inquote = !inquote;
if(!inquote && !isspace(command[place + 1]))
{
temp[tempplace++] = ' ';
}
}
else
{
temp[tempplace++] = command[place];
}
place++;
}
temp[tempplace] = 0;
strcpy(command, temp);
if(inquote)
{
return(0);
}
else
{
return(1); /* true on success */
}
}
/*
* split the command-line into parameters. works with quotation marks.
*
*
*/
unsigned char split(char *command, char *p[128])
{
unsigned char count;
unsigned char place = 1;
unsigned char len;
unsigned char inquote = 0;
p[0] = command;
len = strlen (command);
for(count = 0; count < len; count++)
{
if(command[count] == '"')
{
inquote = !inquote;
}
else if(isspace (command[count]) && !inquote)
{
command[count] = 0;
p[place++] = &command[count + 1];
}
}
p[place] = NULL;
return(place);
}
/* returns TRUE if the char is a delimiter char (i.e. can't be in a filename) */
char is_special(char ch)
{
return(ch == '<' || ch == '>' || ch == '=' || ch == ',' || ch == ';' ||
ch == ':' || ch == '*' || ch == '?' || ch == '[' || ch == ']' ||
ch == '/' || ch == '\\'|| ch == '+' || ch == '"' || ch <= ' ' ||
ch == '|');
}
/*
* execute this as an external program
*
*
*/
void execute (char *s)
{
char cmd[128], *p[128], *paths[129], fullname[128];
int args, r;
/* vars needed for the new EXEC stuff */
char *start;
strcpy (cmd, s);
if (!strip (cmd))
{
fprintf (stderr, "%s\n", SYNTAXERR); /* unmatched quotes */
return;
}
args = split (cmd, p);
/* check this for shortcut commands and the like */
if(p[0][0] && p[0][1] == ':' && p[0][2] == 0) /* change drives */
{
if(isalpha(p[0][0]))
{
setdisk(toupper(p[0][0]) - 'A');
}
if(getdisk () != toupper(p[0][0]) - 'A')
{
printf("%s\n", INVALIDDRIVE);
}
return;
}
else if (memicmp (p[0], CD, 2) == 0 && (p[0][2] == '\\' || p[0][2] == '.'))
{
cd(args, p, s);
return;
}
else if (memicmp (p[0], MD, 2) == 0 && (p[0][2] == '\\' || p[0][2] == '.'))
{
md(args, p, s);
return;
}
else if (memicmp (p[0], RD, 2) == 0 && (p[0][2] == '\\' || p[0][2] == '.'))
{
rd(args, p, s);
return;
}
/* we need to search OUR path for the binary... use my searching algo */
get_paths(paths);
if(!find_which(paths, p[0], fullname))
{
fprintf(stderr, "%s\n", FILENOTFOUND);
return;
}
start = s; /* point to command-line params */
while(isspace(*start))
{
start++;
}
while(*start != 0 && !is_delim (*start))
{
start++;
}
while(isspace(*start))
{
start++;
}
if(!stricmp(strrchr(fullname,'.') + 1, "bat"))
{
batch(fullname, args, p);
}
else if((r = exec(fullname, start, EnvSeg)) != 0)
{
switch(r)
{
case 1 :
{
printf("%s\n", INVALIDFUNCTION);
break;
}
case 2 :
{
printf("%s\n", FILENOTFOUND);
break;
}
case 5 :
{
printf("%s\n", ACCESSDENIED);
break;
}
case 8 :
{
printf("%s\n", NOTENOUGHMEMORY);
break;
}
case 10 :
{
printf("%s\n", BADENVIROMENT);
break;
}
case 11 :
{
printf("%s\n", BADFORMAT);
break;
}
default :
{
printf("ERROR: unknown error %d.\n", errno);
break;
}
}
}
}
/* move this somewhere else later */
static struct CMD
{
char *name;
void (*func)(int, char *[128], char *);
} cmds[] = { { "DIR", dir },
{ "CD", cd },
{ "RD", rd },
{ "MD", md },
{ "DEL", del },
{ "REN", ren },
{ "REM", rem },
{ "DOSKEY", doskey },
{ "EXIT", internal_exit },
{ "VER", ver },
{ "SET", set },
{ "PROMPT", prompt },
{ "LH", loadhigh },
{ "LOADHIGH", loadhigh },
{ "LOADFIX", loadfix },
{ NULL, NULL } };
/*
* run this command
*
*
*/
void command (char *s)
{
char line[256]; /* just a little extra space :) */
char com[128]; /* the first word in the command */
int count, start;
int executed = 0; /* whether the command was executed */
strcpy (line, s);